package com.lixin.admin.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lixin.admin.server.convert.AdminCreateConvert;
import com.lixin.admin.server.convert.AdminUpdateConvert;
import com.lixin.admin.server.dao.AdminMapper;
import com.lixin.admin.server.model.Admin;
import com.lixin.admin.server.model.AdminRole;
import com.lixin.admin.server.service.AdminRoleService;
import com.lixin.admin.server.service.AdminService;
import com.lixin.admin.server.utils.MD5Utils;
import com.lixin.admin.server.vo.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    @Resource
    private AdminRoleService adminRoleService;

    @Value("${paging.record-num-max}")
    private Long recordNum;

    @Override
    public List<AdminVO> getList(AdminSearchVO adminSearchVO) {
        Long recordNum = adminSearchVO.getRecordNum() >= this.recordNum ? this.recordNum : adminSearchVO.getRecordNum();
        recordNum = recordNum <= 0 ? 50 : recordNum;
        Long startIndex = (adminSearchVO.getCurPage() - 1) * recordNum;
        adminSearchVO.setStartIndex(startIndex);
        return this.baseMapper.getList(adminSearchVO);
    }

    @Override
    @Transactional
    public boolean create(AdminCreateVO adminCreateVO) {
        Admin admin = AdminCreateConvert.INSTANCE.vo2entity(adminCreateVO);
        String password = MD5Utils.encode(MD5Utils.encode(adminCreateVO.getAdminPassword()));
        admin.setAdminPassword(password);
        admin.setAdminCreated(LocalDateTime.now());
        admin.setAdminUpdated(LocalDateTime.now());
        this.baseMapper.addAdmin(admin);
        if (admin.getAdminId() <= 0) return false;

        List<AdminRole> adminRoleList = new ArrayList<>();
        for (Long roleId : adminCreateVO.getAdminRoleIdList()) {
            AdminRole adminRole = new AdminRole();
            adminRole.setAdminId(admin.getAdminId());
            adminRole.setRoleId(roleId);
            adminRoleList.add(adminRole);
        }
        return adminRoleService.saveBatch(adminRoleList);
    }

    @Override
    @Transactional
    public boolean modify(AdminUpdateVO adminUpdateVO) {
        Admin admin = AdminUpdateConvert.INSTANCE.vo2entity(adminUpdateVO);
        if (adminUpdateVO.getAdminPassword().length() > 0) {
            String password = MD5Utils.encode(MD5Utils.encode(adminUpdateVO.getAdminPassword()));
            admin.setAdminPassword(password);
        } else {
            admin.setAdminPassword(null);
        }
        admin.setAdminUpdated(LocalDateTime.now());
        if (!updateById(admin)) return false;

        List<Long> roleIds = adminUpdateVO.getAdminRoleIdList();
        if (roleIds.size() > 0) {
            QueryWrapper<AdminRole> qw = new QueryWrapper<>();
            qw.eq("admin_id", adminUpdateVO.getAdminId());
            if (!adminRoleService.remove(qw)) return false;

            List<AdminRole> adminRoleList = new ArrayList<>();
            for (Long roleId : roleIds) {
                AdminRole adminRole = new AdminRole();
                adminRole.setAdminId(adminUpdateVO.getAdminId());
                adminRole.setRoleId(roleId);
                adminRoleList.add(adminRole);
            }
            return adminRoleService.saveBatch(adminRoleList);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean del(AdminDelVO adminDelVO) {
        List<Long> adminIds = adminDelVO.getIds();
        if (!removeByIds(adminIds)) return false;

        for (Long adminId : adminIds) {
            QueryWrapper<AdminRole> qw = new QueryWrapper<>();
            qw.eq("admin_id", adminId);
            if (!adminRoleService.remove(qw)) return false;
        }
        return true;
    }
}
